package com.li.demo001;

import androidx.appcompat.app.AppCompatActivity;

import android.app.Service;
import android.os.Bundle;
import android.os.Vibrator;
import android.view.View;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.TextView;

import java.math.BigDecimal;
import java.math.MathContext;

//后缀表达式数组类
class funcSeqStack{
    String[] data;
    int top;

    public funcSeqStack(){
        data=new String[60];
        top=0;
    }
    public void initStack(){
        data=new String[60];
        top=0;
    }
    public void insert(String str){
        data[top]=str;
        top++;
    }
    public String pop(){
        top--;
        return data[top];
    }
    public String gettop(){
        return data[top-1];
    }
    public void displayContent() {
        for (int i = 0; i <top; i++) {
            System.out.print("func的第"+i+"：");
            System.out.println(data[i]);

        }
        System.out.println("func的top:"+top);
        System.out.println("");
    }

}
//操作符数组类
class operaSeqStack{
    char[] data;
    int top;

    public operaSeqStack(){
        data=new char[20];
        top=0;
    }
    public void initStack(){
        data=new char[20];
        top=0;
    }
    public void insert(char str){
        data[top]=str;
        top++;
    }
    public char pop(){
        top--;
        return data[top];
    }
    public char getTop(){
        return data[top-1];
    }
    public void displayContent() {
        for (int i = 0; i <top; i++) {
            System.out.print("opera的第"+i+"：");
            System.out.println(data[i]);

        }
        System.out.println("opera的top:"+top);
        System.out.println("");
    }
}
//运算结果数组类
class numSeqStack{
    double[] data;
    int top;

    public numSeqStack(){
        data=new double[60];
        top=0;
    }
    public void initStack(){
        data=new double[60];
        top=0;
    }
    public void insert(String str){
        data[top]=Double.parseDouble(str);
        top++;
    }
    public void insert(double num){
        data[top]=num;
        top++;
    }
    public double pop(){
        top--;
        return data[top];
    }
    public double getTop(){
        return data[top-1];
    }
    public void displayContent() {
        for (int i = 0; i <top; i++) {

            System.out.print("num的第"+i+"：");
            System.out.println(data[i]);


        }
        System.out.println("num的top:"+top);
        System.out.println("");
    }
}

//操作类
class operation{

    double result;
    String str;
    funcSeqStack fss;
    operaSeqStack oss;
    numSeqStack nss;

    public operation(){
        result=0;
        fss=new funcSeqStack();
        oss=new operaSeqStack();
        nss=new numSeqStack();
    }

    //比较两个运算符的优先级
    //a，b中存放待比较的运算符
    //'>'表示a>b
    //'0'表示不可能出现的比较
    public char compare(char a, char b){
        int i = 0,j = 0;
        char[][] pre = new char[][]{
                /*运算符之间的优先级制作成一张表格*/
                {'=', '<', '<', '<',  '>'},
                {'<', '=', '<', '<',  '>'},
                {'>', '>', '=', '<',  '>'},
                {'>', '>', '<', '=',  '>'},
                {'<', '<', '<', '<',  '='}};
        switch(a){
            case '+': i=0; break;
            case '-': i=1; break;
            case '×': i=2; break;
            case '÷': i=3; break;
            //case '#': i=6; break;
        }
        switch(b){
            case '+': j=0; break;
            case '-': j=1; break;
            case '×': j=2; break;
            case '÷': j=3; break;
            //case '#': j=6; break;
        }
        return pre[i][j];
    }

    //检查表达式是否正确
    public boolean checkFunction(String str1){
        int i,tempi=-1;
        char tempChar1,tempChar2,tempChar3;
        double tempDouble;
        this.str=str1+"!";//接收到传来的String型的待求值表达式
        //遍历表达式
        for(i = 0; i <str.length(); i++){


            if (str.length()<=1){
                tempChar1=str.charAt(i);
                if ((tempChar1=='+'||tempChar1=='-'||tempChar1=='×'||tempChar1=='÷'||tempChar1=='!')){
                    return false;
                }
            }else{
                tempChar1=str.charAt(i);
                if (tempChar1=='!') break;
                tempChar2=str.charAt(i+1);
                if (i==0&&(tempChar1=='+'||tempChar1=='-'||tempChar1=='×'||tempChar1=='÷')){
                    return false;
                }
                if ((tempChar1=='+'||tempChar1=='-'||tempChar1=='×'||tempChar1=='÷')&&(tempChar2=='+'||tempChar2=='-'||tempChar2=='×'||tempChar2=='÷')){
                    return false;
                }
                if ((tempChar1=='+'||tempChar1=='-'||tempChar1=='×'||tempChar1=='÷')&&tempChar2=='!'){
                    return false;
                }
                if ((tempChar1=='÷')&&(tempChar2=='0')){
                    tempi=i;
                    do {
                        tempi++;
                        tempChar3=str.charAt(tempi);
                    }while (!(tempChar3=='+'||tempChar3=='-'||tempChar3=='×'||tempChar3=='÷'||tempChar3=='!'));
                    tempDouble=Double.parseDouble(str.substring(i+1,tempi));
                    if (tempDouble!=0.0){
                        return true;
                    }
                    return false;
                }
            }


        }

        return true;
    }
    //中缀表达式转后缀表达式
    public void changeFunction(){

        int i,tempi=-1;//i用于遍历str表达式,tempi用于存放上个操作符的位置
        boolean insertFlag;
        //遍历中缀表达式
        for(i = 0; i <str.length(); i++) {
            char c = str.charAt(i);
            // System.out.print(c);
            insertFlag=true;
            if(c=='+'||c=='-'||c=='×'||c=='÷'||c=='!'){
                //整理操作数，入后缀表达式数组
                fss.insert(""+Double.parseDouble(str.substring(tempi+1,i)));
                tempi=i;
//              System.out.println("");
//              System.out.println("tempi:+1:   "+(tempi+1)+"    i:"+i);
//              tempi=i;
                //操作符入操作符数组
                if(c!='!') {
                    do {
//            		  System.out.println("");
//            		  System.out.println("oss.top："+(oss.top==0));

                        if(oss.top==0){
                            oss.insert(c);
                            insertFlag=false;
                        }else{
//	                	  System.out.println(compare(c,oss.getTop()));
                            switch (compare(c,oss.getTop())) {
                                case '>':
                                    oss.insert(c);
                                    insertFlag=false;
                                    break;
                                case '=':
                                case '<':
                                    fss.insert(""+oss.pop());
//	                              System.out.println(oss.top);
                                    break;
                            }
                        }
//	                  System.out.println(insertFlag);
                    }while (insertFlag);
                }else {
                    //将操作符数组中剩余的操作符插入后缀表达式
                    // oss.displayContent();
                    while(oss.top>0) {

                        oss.getTop();
                        fss.insert(""+oss.pop());
                    }
                    //归位指针
                    oss.top=0;
                }
            }
        }
    }

    //计算
    public double calculate() {
        double x=0;
        double num1,num2,tempResult=0;
        for (int i = 0; i <fss.top; i++){
            if(!(fss.data[i].equals("+")||fss.data[i].equals("-")||fss.data[i].equals("×")||fss.data[i].equals("÷"))){
                nss.insert(fss.data[i]);
            }else{
                num2=nss.pop();
                num1=nss.pop();
                switch (fss.data[i]){
                    case "+":tempResult=num1+num2;break;
                    case "-":tempResult=num1-num2;break;
                    case "×":tempResult=num1*num2;break;
                    case "÷":
                        if(num2!=0) tempResult=num1/num2;
                        if(num2==0) {
                            MainActivity.equalView.setText("错误！除数不能为零");
                            break;
                        }
                        break;
                }
                nss.insert(tempResult);
            }
        }
        x=nss.data[0];
        return x;
    }
    //操作
    public double operate(String str1){
        //初始化各数组
        fss.initStack();
        oss.initStack();
        nss.initStack();

        this.str=str1+"!";//接收到传来的String型的待求值表达式
        changeFunction();//中缀转后缀

//      System.out.println(" ");
//      fss.displayContent();
//      oss.displayContent();
//      nss.displayContent();
        result=calculate();
//        BigDecimal b = new BigDecimal(result);
//        result = b.setScale(5, BigDecimal.ROUND_HALF_UP).doubleValue();

        return result;
    }

}

public class MainActivity extends AppCompatActivity implements View.OnClickListener{

    Button btn0;
    Button btn1;
    Button btn2;
    Button btn3;
    Button btn4;
    Button btn5;
    Button btn6;
    Button btn7;
    Button btn8;
    Button btn9;
    Button btnPoint;
    Button btnAC;
    ImageButton btnDelete;
    Button btnAdd;
    Button btnSub;
    Button btnMulti;
    Button btnDivide;
    Button btnExcess;//%
    Button btnEqual;
    Button btnChange;
    static TextView equalView;
    TextView functionView;
    TextView historyView;

    String str1;//初始输入的表达式
    String str2;//上次运算获得的结果
    String str3;//上次运算的表达式即结果
    char finalChar;//用于delete按钮响应中，暂存最后一个字符
    boolean historyFlag;//是否返回历史表达式的标志
    boolean resultFlag;//是否得到结果的标志
    boolean pointFlag;//小数点是否在一个数里被使用过的标志
    operation op;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);
        initView();  //初始化布局
        str1="";
        str2="";
        historyFlag=false;
        resultFlag=false;
        pointFlag=false;
        op=new operation();

    }

    public void onClick(View view) {
        Vibrator vibrator=(Vibrator)getSystemService(Service.VIBRATOR_SERVICE);
        vibrator.vibrate(new long[]{0,20}, -1);
        switch (view.getId()) {
            case R.id.btn0:
                if(resultFlag==true){
                    str1="";
                    str2="";
                    resultFlag=false;
                }
                if(str1.equals("0")){
                    str1="0";
                }else{
                    str1 = str1+((Button) view).getText().toString();
                }
                functionView.setTextSize(50);
                functionView.setText(str1);
                equalView.setText("=");
                break;
            case R.id.btn1:
            case R.id.btn2:
            case R.id.btn3:
            case R.id.btn4:
            case R.id.btn5:
            case R.id.btn6:
            case R.id.btn7:
            case R.id.btn8:
            case R.id.btn9:
                if(resultFlag==true){
                    str1="";
                    str2="";
                    resultFlag=false;
                }
                if(str1.equals("0")){
                    str1 = ((Button) view).getText().toString();
                }else{
                    str1 = str1+((Button) view).getText().toString();
                }
                functionView.setTextSize(50);
                functionView.setText(str1);
                equalView.setText("=");
                break;
            case R.id.btnPoint:
                if(resultFlag==true){
                    str1="";
                    str2="";
                    resultFlag=false;
                }
                if(str1.equals("")){
                    str1="0.";
                    pointFlag=true;
                }else{
                    String lastChar=str1.substring(str1.length()-1);
                    if(lastChar.equals("+")||lastChar.equals("-")||lastChar.equals("×")||lastChar.equals("÷")){
                        str1=str1+"0.";
                        pointFlag=true;
                    }
                }
                if(pointFlag==false){
                    str1 = str1+((Button) view).getText().toString();
                    pointFlag=true;
                }
                functionView.setTextSize(50);
                functionView.setText(str1);
                equalView.setText("=");
                break;
            case R.id.btnAdd:
            case R.id.btnSub:
            case R.id.btnMulti:
            case R.id.btnDivide:
                pointFlag=false;
                if(resultFlag==true){
                    str1 = str2+((Button) view).getText().toString();
                    resultFlag=false;
                }else{
                    str1 = str1+((Button) view).getText().toString();
                }
                functionView.setTextSize(50);
                functionView.setText(str1);
                equalView.setText("=");
                break;
            case R.id.btnAC:
                clear();
                break;

            case R.id.btnDelete:
                if(resultFlag==true){
                    clear();
                }else{
                    if(str1.length()>1){
                        finalChar=str1.charAt(str1.length()-1);
                        if (finalChar=='+'||finalChar=='-'||finalChar=='×'||finalChar=='÷'){
                            pointFlag=true;
                        }
                        str1=str1.substring(0,str1.length()-1);
                        functionView.setTextSize(50);
                        functionView.setText(str1);
                    }else{
                        clear();
                    }
                }
                break;

            case R.id.btnEqual:
                if(op.checkFunction(str1)){
                    double tempResult=op.operate(str1);
                    if ((tempResult+"").length()-(tempResult+"").indexOf(".")-1>6){
                        //保留8位有效数字
                        BigDecimal b = new BigDecimal(String.valueOf(tempResult));
                        str2="" + b.divide(BigDecimal.ONE, new MathContext(8));
                    }else{
                        str2=""+tempResult;
                    }
                    equalView.setTextSize(50);
                    functionView.setTextSize(30);
                    equalView.setText("="+str2);
                    historyFlag=true;
                }else{
                    equalView.setTextSize(50);
                    functionView.setTextSize(30);
                    equalView.setText("表达式错误！");
                    historyFlag=false;
                }
                resultFlag=true;
                break;
        }
        if(historyFlag==true){
            str3=str1+"="+str2;
            historyView.setTextSize(30);
            historyView.setText(str3);
            historyFlag=false;
        }

    }


    public void initView(){
        btn0 = (Button) findViewById(R.id.btn0);
        btn1 = (Button) findViewById(R.id.btn1);
        btn2 = (Button) findViewById(R.id.btn2);
        btn3 = (Button) findViewById(R.id.btn3);
        btn4 = (Button) findViewById(R.id.btn4);
        btn5 = (Button) findViewById(R.id.btn5);
        btn6 = (Button) findViewById(R.id.btn6);
        btn7 = (Button) findViewById(R.id.btn7);
        btn8 = (Button) findViewById(R.id.btn8);
        btn9 = (Button) findViewById(R.id.btn9);
        btnPoint = (Button) findViewById(R.id.btnPoint);
        btnAC = (Button) findViewById(R.id.btnAC);
        btnAdd = (Button) findViewById(R.id.btnAdd);
        btnSub = (Button) findViewById(R.id.btnSub);
        btnMulti = (Button) findViewById(R.id.btnMulti);
        btnDivide = (Button) findViewById(R.id.btnDivide);
        btnDelete = (ImageButton) findViewById(R.id.btnDelete);
        btnEqual = (Button) findViewById(R.id.btnEqual);
        //btnExcess = (Button) findViewById(R.id.btnExcess);
        functionView = (TextView)findViewById(R.id.functionView);
        equalView = (TextView)findViewById(R.id.equalView);
        historyView = (TextView)findViewById(R.id.historyView);

        btn0.setOnClickListener(this);
        btn1.setOnClickListener(this);
        btn2.setOnClickListener(this);
        btn3.setOnClickListener(this);
        btn4.setOnClickListener(this);
        btn5.setOnClickListener(this);
        btn6.setOnClickListener(this);
        btn7.setOnClickListener(this);
        btn8.setOnClickListener(this);
        btn9.setOnClickListener(this);
        btnPoint.setOnClickListener(this);
        btnAC.setOnClickListener(this);
        btnAdd.setOnClickListener(this);
        btnSub.setOnClickListener(this);
        btnMulti.setOnClickListener(this);
        btnDivide.setOnClickListener(this);
//        btnExcess.setOnClickListener(this);
        btnEqual.setOnClickListener(this);
        btnDelete.setOnClickListener(this);
    }


    public void clear() {
        str1 = "";
        str2 = "";
        pointFlag=false;
        resultFlag=false;
        equalView.setText("");
        functionView.setText("");
    }
}
